function kongZhi(camera, scene, renderer, jueSe, isPc, tongBuWuTi, shuaXinUI, juJiJing, physicsAddMesh,
	physicsSetMeshPosition,
	ws, huoYan, listener, audioLoader, firetorch_1) {

	let blocker = document.getElementById('blocker');
	let isLock = false;

	let yaoGan = document.getElementById('yao-gan');

	let velocity = new THREE.Vector3();
	let direction = new THREE.Vector3();

	const _euler = new THREE.Euler(0, 0, 0, 'YXZ'); //相机用
	const jueSeEuler = new THREE.Euler(0, 0, 0, 'YXZ'); //角色用
	const jueSeBoneEuler = new THREE.Euler(0, 0, 0, 'YXZ'); //角色骨骼动作用
	const _quaternion = new THREE.Quaternion().copy(jueSe.quaternion); //基准旋转四元数
	const jueSeQuaternion = new THREE.Quaternion().copy(jueSe.quaternion);
	const jueSeBoneQuaternion = new THREE.Quaternion().copy(jueSe.quaternion);
	const _vector = new THREE.Vector3();
	const _PI_2 = Math.PI / 2;
	const minPolarAngle = 0;
	const maxPolarAngle = Math.PI;

	let moveForward = false;
	let moveBackward = false;
	let moveLeft = false;
	let moveRight = false;
	let space = false;
	let keDaJi = true;
	let yiDongZhuangTai = false;

	jueSe.userData.keTiao = false; //是否可跳

	//给服务端发送信息
	function faSongXinXi() {
		
		let jueSeJson = {
			jueSeHao: jueSe.userData.jueSeHao,
			weiZhi: {
				x: jueSe.position.x,
				y: jueSe.position.y,
				z: jueSe.position.z
			},
			xuanZhuan: {
				x: jueSe.quaternion.x,
				y: jueSe.quaternion.y,
				z: jueSe.quaternion.z,
				w: jueSe.quaternion.w
			},
			dongZuo: jueSe.userData.dongZuo.zhuangTai,
			niuZhuan: {
				x: jueSe.userData.xiongBone.quaternion.x,
				y: jueSe.userData.xiongBone.quaternion.y,
				z: jueSe.userData.xiongBone.quaternion.z,
				w: jueSe.userData.xiongBone.quaternion.w
			},
			woDaJi: jueSe.userData.woDaJi
		}
		ws.send(JSON.stringify(jueSeJson));
	}

	function lock() {
		blocker.style.display = 'none';
	}

	function unlock() {
		blocker.style.display = 'flex';
	}

	function onMouseMove(event) {

		if (isPc === false || isLock === false) return;

		const movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
		const movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;

		_euler.setFromQuaternion(_quaternion);
		jueSeEuler.setFromQuaternion(jueSeQuaternion);

		_euler.y -= movementX * 0.001; //左右旋转
		jueSeEuler.y -= movementX * 0.001; //左右旋转

		_euler.x -= movementY * 0.001; //上下旋转
		jueSeBoneEuler.x -= movementY * 0.001; //上下旋转

		_euler.x = Math.max(_PI_2 - maxPolarAngle, Math.min(_PI_2 - minPolarAngle, _euler.x)); //锁定上下90
		jueSeBoneEuler.x = Math.max(_PI_2 - maxPolarAngle, Math.min(_PI_2 - minPolarAngle, jueSeBoneEuler.x));

		_quaternion.setFromEuler(_euler);
		jueSeQuaternion.setFromEuler(jueSeEuler);
		jueSeBoneQuaternion.setFromEuler(jueSeBoneEuler);

		camera.quaternion.copy(_quaternion);

		jueSe.quaternion.copy(jueSeQuaternion);
		jueSe.userData.xiongBone.quaternion.copy(jueSeBoneQuaternion);

	}

	function onWindowResize() {

		let width = Math.max(window.innerWidth, window.innerHeight);
		let height = Math.min(window.innerWidth, window.innerHeight);

		camera.aspect = width / height;
		camera.updateProjectionMatrix();
		renderer.setSize(width, height);
	}

	function onKeyDown(event) {

		switch (event.code) {

			case 'ArrowUp':
			case 'KeyW':
				moveForward = true;
				break;

			case 'ArrowLeft':
			case 'KeyA':
				moveLeft = true;
				break;

			case 'ArrowDown':
			case 'KeyS':
				moveBackward = true;
				break;

			case 'ArrowRight':
			case 'KeyD':
				moveRight = true;
				break;

			case 'Space':
				space = true;
				break;

		}

	};

	function onKeyUp(event) {

		switch (event.code) {

			case 'ArrowUp':
			case 'KeyW':
				moveForward = false;
				break;

			case 'ArrowLeft':
			case 'KeyA':
				moveLeft = false;
				break;

			case 'ArrowDown':
			case 'KeyS':
				moveBackward = false;
				break;

			case 'ArrowRight':
			case 'KeyD':
				moveRight = false;
				break;

			case 'Space':
				space = false;

		}

	};



	function daJi() {

		if (keDaJi) {

			keDaJi = false;
			setTimeout(() => keDaJi = true, 1000);

			const pos = new THREE.Vector3();
			const quat = new THREE.Quaternion();

			const ball = new THREE.Mesh(new THREE.BoxGeometry(0.02, 0.02, 1), new THREE.MeshPhongMaterial({
				color: 0x995500
			}));
			ball.userData.changDu = 1;
			ball.userData.kuaiSuWuTi = true;

			let vel = new THREE.Vector3()
			vel.copy(camera.getWorldDirection(vel));
			vel.y += 0.001;

			let suDuLiang = 150; //米每秒

			ball.userData.suDu = suDuLiang;
			vel.multiplyScalar(suDuLiang);

			ball.rotateX(-Math.PI / 2);
			ball.applyQuaternion(camera.quaternion);

			pos.copy(camera.position);
			pos.addScaledVector(camera.getWorldDirection(new THREE.Vector3()), 1);
			pos.y -= 0.01;

			ball.position.copy(pos);

			ball.layers.enable(1); //添加层1
			scene.add(ball)
			physicsAddMesh(ball, 50);
			physicsSetMeshPosition(ball, pos, vel);

			//枪口火焰
			let qiangKouHuoYan = huoYan(firetorch_1);
			qiangKouHuoYan.position.copy(camera.position);
			qiangKouHuoYan.quaternion.copy(camera.quaternion);
			const e = jueSe.matrixWorld.elements;
			let jueSeDirection = new THREE.Vector3().set(-e[8], -e[9], -e[10]).normalize();
			qiangKouHuoYan.position.addScaledVector(jueSeDirection, 1.2);
			qiangKouHuoYan.position.y -= 0.5;
			scene.add(qiangKouHuoYan);
			setTimeout(() => scene.remove(qiangKouHuoYan), 130)

			//枪声
			jueSe.children.forEach(audio => {
				if (audio.type == 'Audio') jueSe.remove(audio);
			})

			const audio = new THREE.PositionalAudio(listener);
			audio.setBuffer(jueSe.userData.qiangShengBuffer);
			audio.setVolume(0.4);
			jueSe.add(audio);
			jueSe.userData.qiangSheng = audio;
			audio.play();
		}



	}

	function miaoZhun() {
		if (!jueSe.userData.miaoZhun) {
			juJiJing();
			camera.zoom = 6;
			camera.updateProjectionMatrix();
			jueSe.visible = false;
			jueSe.userData.miaoZhun = true;
		} else {
			shuaXinUI(jueSe.userData.xueLiang);
			camera.zoom = 1;
			camera.updateProjectionMatrix();
			jueSe.visible = true;
			jueSe.userData.miaoZhun = false;
		}
	}

	window.addEventListener('resize', onWindowResize);

	document.addEventListener('keydown', onKeyDown);
	document.addEventListener('keyup', onKeyUp);
	document.addEventListener('mousemove', onMouseMove);

	document.addEventListener('mousedown', () => {
		//解锁后再锁需要大概2秒间隔
		if (isPc) document.body.requestPointerLock();
	});
	document.addEventListener('pointerlockchange', event => {
		isLock = (document.pointerLockElement == document.body);
		if (isLock) lock();
		else unlock();
	});

	document.oncontextmenu = function(event) {
		event.preventDefault();
	};

	if (isPc) window.addEventListener('pointerdown', event => {

		if (event.button === 0) daJi();
		if (event.button === 2) miaoZhun();
	}); //攻击

	//手机端
	if (!isPc) {

		let yiDongShiVec2 = new THREE.Vector2();
		let yiDongZhongVec2 = new THREE.Vector2();

		let touchStartX, touchStartY;

		// document.getElementById('key-w').addEventListener('touchstart', () => moveForward = true);
		// document.getElementById('key-w').addEventListener('touchend', () => moveForward = false);
		// document.getElementById('key-s').addEventListener('touchstart', () => moveBackward = true);
		// document.getElementById('key-s').addEventListener('touchend', () => moveBackward = false);
		// document.getElementById('key-a').addEventListener('touchstart', () => moveLeft = true);
		// document.getElementById('key-a').addEventListener('touchend', () => moveLeft = false);
		// document.getElementById('key-d').addEventListener('touchstart', () => moveRight = true);
		// document.getElementById('key-d').addEventListener('touchend', () => moveRight = false);

		document.getElementById('tiao').addEventListener('touchstart', () => space = true);
		document.getElementById('tiao').addEventListener('touchend', () => space = false);

		document.getElementById('miao-zhun').addEventListener('touchstart', () => miaoZhun());

		yaoGan.addEventListener('touchstart', event => {
			yiDongShiVec2.set(event.targetTouches[0].pageX, event.targetTouches[0].pageY);
			event.preventDefault()
		});
		yaoGan.addEventListener('touchmove', event => {
			let vec2 = new THREE.Vector2(event.targetTouches[0].pageX, event.targetTouches[0].pageY);
			let juLi = vec2.distanceTo(yiDongShiVec2);

			//插值坐标在半径75的圆上
			if (juLi > 75) {
				let alpha = 75 / juLi;
				yiDongZhongVec2.lerpVectors(yiDongShiVec2, vec2, alpha);
			} else yiDongZhongVec2.copy(vec2);

			yaoGan.style.top = `${75 - (yiDongZhongVec2.x - yiDongShiVec2.x)}px`;
			yaoGan.style.left = `${75 + (yiDongZhongVec2.y - yiDongShiVec2.y)}px`;

			direction.z = -(yiDongZhongVec2.x - yiDongShiVec2.x);
			direction.x = yiDongZhongVec2.y - yiDongShiVec2.y;
			direction.normalize();

			yiDongZhuangTai = true;
			event.preventDefault()
		});
		yaoGan.addEventListener('touchend', event => {
			yaoGan.style.top = `${75}px`;
			yaoGan.style.left = `${75}px`;

			yiDongZhuangTai = false;

			event.preventDefault()
		});

		document.getElementById('shi-jiao').addEventListener('touchstart', event => {
			touchStartX = event.targetTouches[0].pageX;
			touchStartY = event.targetTouches[0].pageY;
			event.preventDefault()
		});

		document.getElementById('shi-jiao').addEventListener('touchmove', event => {

			let touchEndX = event.targetTouches[0].pageX;
			let touchEndY = event.targetTouches[0].pageY;

			const movementX = touchEndX - touchStartX;
			const movementY = touchEndY - touchStartY;

			touchStartX = touchEndX;
			touchStartY = touchEndY;

			_euler.setFromQuaternion(_quaternion);
			jueSeEuler.setFromQuaternion(jueSeQuaternion);

			_euler.y -= movementY * 0.01; //左右旋转，绕y轴
			jueSeEuler.y -= movementY * 0.01; //左右旋转

			_euler.x += movementX * 0.01; //上下旋转，绕x轴
			jueSeBoneEuler.x += movementX * 0.01; //上下旋转

			_euler.x = Math.max(_PI_2 - maxPolarAngle, Math.min(_PI_2 - minPolarAngle, _euler.x)); //锁定上下90
			jueSeBoneEuler.x = Math.max(_PI_2 - maxPolarAngle, Math.min(_PI_2 - minPolarAngle, jueSeBoneEuler
				.x));

			_quaternion.setFromEuler(_euler);
			jueSeQuaternion.setFromEuler(jueSeEuler);
			jueSeBoneQuaternion.setFromEuler(jueSeBoneEuler);

			camera.quaternion.copy(_quaternion);
			jueSe.quaternion.copy(jueSeQuaternion);
			jueSe.userData.xiongBone.quaternion.copy(jueSeBoneQuaternion);

		});

		document.getElementById('da-ji').addEventListener('touchend', daJi); //攻击
	}



	function yiDong(deltaTime) {

		let _vector = new THREE.Vector3;
		let _vector1 = new THREE.Vector3;

		if (isPc) {
			if (!(moveForward && moveBackward)) velocity.z = 0;
			if (!(moveLeft && moveRight)) velocity.x = 0;

			direction.z = Number(moveForward) - Number(moveBackward);
			direction.x = Number(moveRight) - Number(moveLeft);

			if (moveForward || moveBackward) velocity.z -= direction.z * 4;
			if (moveLeft || moveRight) velocity.x -= direction.x * 4;

			//左右移动
			_vector.setFromMatrixColumn(jueSe.matrix, 0);
			_vector1.addScaledVector(_vector, -velocity.x);

			//前后移动
			_vector.setFromMatrixColumn(jueSe.matrix, 0);
			_vector.crossVectors(jueSe.up, _vector);
			_vector1.addScaledVector(_vector, -velocity.z);

		} else {
			if (yiDongZhuangTai) {
				_vector1.addScaledVector(direction, 4);
				_vector1.applyQuaternion(jueSe.quaternion);
			}
		}

		physicsSetMeshPosition(jueSe, undefined, _vector1);

		if (moveForward || moveBackward || moveLeft || moveRight || yiDongZhuangTai) {
			jueSe.userData.physicsBody.setFriction(0);
			jueSe.userData.dongZuo.zhuangTai = 'pao';
			jueSe.userData.dongZuo.zhan.stop();
			jueSe.userData.dongZuo.pao.play();
		} else {
			jueSe.userData.physicsBody.setFriction(4);
			jueSe.userData.dongZuo.zhuangTai = 'zhan';
			jueSe.userData.dongZuo.pao.stop();
			jueSe.userData.dongZuo.zhan.play();
		}

		//跳

		if (jueSe.userData.keTiao && space) {
			_vector1.y = 5;
			physicsSetMeshPosition(jueSe, undefined, _vector1, 'tiao');
			jueSe.userData.keTiao = false;
		}

		camera.position.copy(jueSe.userData.shiDianObj.getWorldPosition(new THREE.Vector3()));

		//胸骨动作
		jueSe.userData.xiongBone.quaternion.copy(jueSeBoneQuaternion);

		//相机后移
		camera.updateWorldMatrix(true, false);
		const e = camera.matrixWorld.elements;
		let cameraDirection = new THREE.Vector3().set(-e[8], -e[9], -e[10]).normalize();

		camera.position.addScaledVector(cameraDirection, -0.35);

		faSongXinXi()

	}

	return {
		yiDong
	}
}

export default kongZhi;
